import { SelfDefFundAccountType } from "./selfDefFundAccountType"
import { CsDouble } from '../common/csDouble.js';
import { Util } from "../../utils/util.js";

export class SelfDefFundDouble {
    _selfDefFundAccountType = null;      // SelfDefFundAccountType
    _expectCount = CsDouble.zero();      // 应收/付
    _count = CsDouble.zero();           // 实收/付    两者差额就是需要往账户里面存余款

    // 下列用于记录贵金属的来金，付金，应收金，应付金
    // 主要用于结算记录
    _inCount = null;  // 收
    _outCount = null;  //  支出
    _inExpectCount = null;  // 应收
    _outExpectCount = null; // 应付

    _balanceBefore = CsDouble.zero();  // 本次记录后前总账余额
    _balanceAfter = CsDouble.zero();  // 本次记录后总账余额


    // type SelfDefFundAccountType
    // count : CsDouble
    constructor(type, count, expectCount, { inCount, outCount, inExpectCount, outExpectCount } = {}) {
        this._selfDefFundAccountType = type;
        this._count = count;
        this._expectCount = expectCount;
        this._inCount = inCount;
        this._outCount = outCount;
        this._inExpectCount = inExpectCount;
        this._outExpectCount = outExpectCount;
    }

    get selfDefFundAccountType() {
        return this._selfDefFundAccountType;
    }

    get count() {
        return this._count;
    }

    // valude CsDboule
    set count(value) {
        this._count = value;
    }

    get expectCount() {
        return this._expectCount;
    }

    set expectCount(value) {
        this._expectCount = value;
    }

    addCount(value) {
        if (this._count == null) {
            return;
        }
        this._count = this._count.add(value);
    }

    subCount(value) {
        if (this._count == null) {
            return;
        }
        this._count = this._count.sub(value);
    }

    addExpectCount(value) {
        if (this._expectCount == null) {
            return;
        }
        this._expectCount = this._expectCount.add(value);
    }

    subExpectCount(value) {
        if (this._expectCount == null) {
            return;
        }
        this._expectCount = this._expectCount.sub(value);
    }

    get inCount() {
        return this._inCount;
    }
    set inCount(value) {
        this._inCount = value;
        this.updateBalanceAfter();
    }
    get outCount() {
        return this._outCount;
    }
    set outCount(value) {
        this._outCount = value;
        this.updateBalanceAfter();
    }
    get inExpectCount() {
        return this._inExpectCount;
    }
    set inExpectCount(value) {
        this._inExpectCount = value;
        this.updateBalanceAfter();
    }

    // 获取收和应收盈余 = 收 - 应收  (客户视角)
    // = 0 表示收和应收没有盈余
    // < 0 表示对方欠款
    // > 0 示对方有盈余
    get inBalance() {
        if (this._inCount != null || this._inExpectCount != null) {
            let inExpectCount = this._inExpectCount ?? CsDouble.zero();
            let inCount = this._inCount ?? CsDouble.zero();
            return inCount.sub(inExpectCount);
        }

        return null;

    }


    get outExpectCount() {
        return this._outExpectCount;
    }
    set outExpectCount(value) {
        this._outExpectCount = value;
        this.updateBalanceAfter();
    }

    // 获取付和应付盈余 = 付 - 应付 (客户视角)
    // = 0 示付和应付没有盈余
    // < 0 示对方欠款
    // > 0 示对方有盈余
    get outBalance() {
        if (this._outCount != null || this._outExpectCount != null) {
            let outExpectCount = this._outExpectCount ?? CsDouble.zero();
            let outCount = this._outCount ?? CsDouble.zero();
            return outExpectCount.sub(outCount);
        }
        return null;
    }
    get balance() {
        return this._balance;
    }

    // value CsDboule
    // 更新总账 = 前总账 + 收盈余 + 付盈余 (均为客户视角，正数客户盈余)
    set balanceBefore(value) {
        if (value == null) {
            console.log("set balanceBefore value is null");
            return;
        }
        this._balanceBefore = value;
        this.updateBalanceAfter();
    }

    get balanceAfter() {
        return this._balanceAfter;
    }

    set balanceAfter(value) {
        this._balanceAfter = value;
    }

    updateBalanceAfter() {
        if (this._balanceBefore != null || this.inBalance != null || this.inBalance != null) {
            let balanceBefore = this._balanceBefore ?? CsDouble.zero();
            let inBalance = this.inBalance ?? CsDouble.zero();
            let outBalance = this.outBalance ?? CsDouble.zero();
            // 总账 = 前总账 + 收盈余 + 付盈余 (均为客户视角，正数客户盈余)
            this._balanceAfter = balanceBefore.add(inBalance).add(outBalance);
        }



    }

    // 克隆方法
    static clone(unit) {
        return new SelfDefFundDouble(SelfDefFundAccountType.clone(unit._selfDefFundAccountType), new CsDouble(unit.count.value), new CsDouble(unit.expectCount.value));
    }


    static fromJson(json) {
        return new SelfDefFundDouble(
            new SelfDefFundAccountType(Util.jsonToString(json.id), 
            Util.jsonToString(json.name), 
            Util.jsonToString(json.code)),
            Util.jsonToCsDouble(json.value), 
            Util.jsonToCsDouble(json.expectValue)
            ,{
                inCount: Util.jsonToCsDouble(json.inCount,null),
                outCount: Util.jsonToCsDouble(json.outCount,null),               
            }
        );
    }

    toJson() {
        return {
            id: this._selfDefFundAccountType.id,
            name: this._selfDefFundAccountType.name,
            code: this._selfDefFundAccountType.code,
            value: this._count.value,
            expectValue: this._expectCount.value,
        };
    }

    toJsonForTransition() {
        let ret = {
            id: this._selfDefFundAccountType.id,
            name: this._selfDefFundAccountType.name,
            code: this._selfDefFundAccountType.code,            
        };

        if(this._inCount != null){
            ret.inCount = this._inCount.value;
        }

        if(this._outCount != null){
            ret.outCount = this._outCount.value;
        }

        return ret;

    }


}